package finalproject.model.player;

import java.util.Iterator;
import java.util.List;

import finalproject.model.items.Item;
import finalproject.model.items.LabItem;
import finalproject.model.items.LectureItem;
import finalproject.model.rooms.Room;
import finalproject.util.datastructure.Association;

public class ItemManager {

	private Association<LectureItem, LabItem, String> workingManager;
	private List<Item> heldItems;
	private int maxWeigth;
	private int currentWeigth;

	/**
	 * construct an item manager
	 * 
	 * @param heldItems
	 * @param maxWeigth
	 * @param currentWeigth
	 * @param workingManager
	 */
	public ItemManager(List<Item> heldItems, int maxWeigth, int currentWeigth,
			Association<LectureItem, LabItem, String> workingManager)
	{
		this.heldItems = heldItems;
		this.maxWeigth = maxWeigth;
		this.currentWeigth = currentWeigth;
		this.workingManager = workingManager;

	}

	/**
	 * 
	 * @return a list of other items
	 */
	public List<Item> getHeldItems()
	{
		return heldItems;
	}

	public void setHeldItems(List<Item> heldItems)
	{
		this.heldItems = heldItems;
	}

	public int getMaxWeigth()
	{
		return maxWeigth;
	}

	public void setMaxWeigth(int maxWeigth)
	{
		this.maxWeigth = maxWeigth;
	}

	public int getCurrentWeigth()
	{
		return currentWeigth;
	}

	public void setCurrentWeigth(int currentWeigth)
	{
		this.currentWeigth = currentWeigth;
	}

	/**
	 * 
	 * @param itemName
	 * @param currentRoom
	 * @return true if the item was taken from the room, false if not
	 */
	public boolean putItemFrom(String itemName, Room currentRoom)
	{
		List<Item> object = currentRoom.getItemList();
		Iterator<Item> iterator = object.iterator();
		Item current;
		while (iterator.hasNext())
		{
			current = iterator.next();
			if (current.getName().equals(itemName) && current.isPickable())
			{

				if (current.isKey())
				{
					workingManager.addKey((LectureItem) current);
				}
				else if (current.isValue())
				{
					workingManager.addValue((LabItem) current);
				}
				else if (!addItem(current))
				{
					return false;
				}
				currentWeigth += current.getweight();
				iterator.remove();
				return true;
			}

		}
		return false;
	}

	/**
	 * add an item (except working items) in the held items list
	 * 
	 * @param current
	 * @return true if the item was added directly, false if not
	 */
	public boolean addItem(Item current)
	{

		if (currentWeigth + current.getweight() < maxWeigth && !contains(current))
		{
			heldItems.add(current);
			currentWeigth += current.getweight();
			return true;
		}
		else
		{
			return false;
		}
	}

	/**
	 * to see if a working item with name is held in the association
	 * 
	 * @param itemName
	 * @return boolean
	 */
	private boolean isInAssociation(String itemName)
	{
		LectureItem lecture = workingManager.getKeyWith(itemName);
		LabItem lab = workingManager.getValueWith(itemName);
		if (lecture == null && lab == null)
		{
			return false;
		}
		else if (workingManager.eraseKey(lecture))
		{
			return true;
		}
		else if (workingManager.eraseValue(lab))
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	/**
	 * methode to drop an item in a room
	 * 
	 * @param itemName
	 * @param currentRoom
	 * @return
	 */
	public boolean drop(String itemName, Room currentRoom)
	{

		Iterator<Item> iterator = heldItems.iterator();
		Item current;
		if (isInAssociation(itemName))
		{
			return true;
		}
		while (iterator.hasNext())
		{
			current = iterator.next();
			if (current.getName().equals(itemName))
			{
				iterator.remove();
				currentRoom.addItem(current);
				currentWeigth -= current.getweight();
				return true;
			}
		}
		return false;
	}

	public boolean contains(Item item)
	{
		for (Item i : heldItems)
		{
			if (i.getName().equals(item.getName()))
			{
				return true;
			}
		}
		return false;
	}

	/**
	 * to get an item (except working item) with a precise name
	 * 
	 * @param s
	 * @return
	 */
	public Item getHeldItem(String s)
	{
		for (Item item : heldItems)
		{
			if (item.getName().equals(s))
			{
				return item;
			}
		}
		LectureItem lect = workingManager.getKeyWith(s);
		if (lect != null)
		{
			return lect;
		}
		else
		{
			return workingManager.getValueWith(s);
		}
	}

	/**
	 * @return the workingManager
	 */
	public Association<LectureItem, LabItem, String> getWorkingManager()
	{
		return workingManager;
	}

	/**
	 * @param workingManager
	 *            the workingManager to set
	 */
	public void setWorkingManager(Association<LectureItem, LabItem, String> workingManager)
	{
		this.workingManager = workingManager;
	}

	/**
	 * Give the specified item to the player.
	 * 
	 * @param itemName
	 *            item name
	 * @param player
	 *            receiver player
	 * @return <code>true</code> if worked, <code>false</code> if item not found
	 */
	public boolean give(String itemName, Player player)
	{
		// Get item
		Item item = getHeldItem(itemName);
		if (item == null)
			return false;

		// Transfer the item
		player.getItemHolder().addItem(item);
		this.heldItems.remove(item);
		return true;
	}
}
